# -*- coding:utf-8 -*-
# --author： jingfeng 
# time: 2018/11/18

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains  #拖拽
import time
from PIL import Image
from lxml import etree
from io import BytesIO
import re

import random
import base64

chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument("--start-maximized")
# 谷歌文档提到需要加上这个属性来规避bug
chrome_options.add_argument('--disable-gpu')
# 设置屏幕器宽高
chrome_options.add_argument("--window-size=1440,750");

driver = webdriver.Chrome(chrome_options=chrome_options)
driver.maximize_window()


def login():
    driver.get('https://www.jd.com/')
    time.sleep(8)
    driver.execute_script('javascript:login();')
    time.sleep(3)
    driver.find_element_by_xpath('//div[@class="login-tab login-tab-r"]/a').click()
    loginname = driver.find_element_by_id('loginname')
    loginname.send_keys('17635395714')
    password = driver.find_element_by_id('nloginpwd')
    password.send_keys('czp0927')

    # 滑块验证码

    submit = driver.find_element_by_id('loginsubmit').click()
    time.sleep(5)

    image = get_image(driver.page_source)

    image1,image2 =get_pictture(image)

    dis = get_distance(image1, image2)
    print('移动距离',dis)


    track_list = get_track(dis-7)
    print(track_list)

    print('第一步,点击滑动按钮')
    element = driver.find_element_by_class_name('JDJRV-slide-btn')
    ActionChains(driver).click_and_hold(
        on_element=element).perform()  # 点击鼠标左键，按住不放
    time.sleep(1)
    print('第二步,拖动元素')
    for track in track_list:
        ActionChains(driver).move_by_offset(xoffset=track,yoffset=0).perform()  # 鼠标移动到距离当前位置（x,y）
        time.sleep(0.002)
    time.sleep(1)
    ActionChains(driver).release(on_element=element).perform()

    time.sleep(1)
    print('第三步,释放鼠标')

    time.sleep(20)
    print(driver.page_source)

    driver.close()

# 和图库对比是哪一幅图

def get_pictture(image2):
    for index in range(1, 11):
        image1 = Image.open('./captcha/index%s.png' % str(index))
        for i in range(0, 10):  # 260
            for j in range(0, 10):  # 160
                pixel1 = image1.getpixel((i, j))
                pixel2 = image2.getpixel((i, j))

                if pixel1 == pixel2:
                    # image1.show()
                    # image2.show()
                    image2.save('image2.png')
                    image1.save('image1.png')
                    return image1, image2


# 得到残图
def get_image(html):
    selector = etree.HTML(html)
    image_url = selector.xpath('//div[@class="JDJRV-bigimg"]/img/@src')[0]
    # 解码得到图片
    url = re.sub('data:image/png;base64,', '', image_url)
    content = base64.urlsafe_b64decode(url + '=' * (4 - len(url) % 4))
    img_file = BytesIO(content)
    image = Image.open(img_file)
    return image


def get_distance(image1, image2):
    '''
      拿到滑动验证码需要移动的距离
      :param image1:没有缺口的图片对象
      :param image2:带缺口的图片对象
      :return:需要移动的距离
      (360, 140)
      '''
    # print('size', image1.size)

    threshold = 60
    for i in range(0, image1.size[0]):
        for j in range(image1.size[1]):
            rgb1 = image1.load()[i, j]
            rgb2 = image2.load()[i, j]
            res1 = abs(rgb1[0] - rgb2[0])
            res2 = abs(rgb1[1] - rgb2[1])
            res3 = abs(rgb1[2] - rgb2[2])
            if not (res1 < threshold and res2 < threshold and res3 < threshold):
                return i


def get_track(distance):
    '''
    拿到移动轨迹，模仿人的滑动行为，先匀加速后匀减速
    匀变速运动基本公式：
    ①v=v0+at
    ②s=v0t+(1/2)at²
    ③v²-v0²=2as

    :param distance: 需要移动的距离
    :return: 存放每0.2秒移动的距离
    '''
    tracks = []
    # 当前位移
    current = 0
    # 减速阈值
    mid = distance * 4 / 5
    # 时间间隔
    t = 0.2
    # 初始速度
    v = 0

    while current < distance:
        if current < mid:
            # 正的加速度，返回随机实数
            a = random.uniform(2,5)
        else:
            a = -(random.uniform(12.5,13.5))
        v0 = v
        v = v0 + a * t
        x = v0 * t + 1 / 2 * a * t * t
        current += x

        if 0.6 < current - distance < 1:
            x = x - 0.53
            tracks.append(round(x,2))

        elif 1 < current - distance < 1.5:
            x = x - 1.4
            tracks.append(round(x,2))
        elif 1.5 < current - distance < 3:
            x = x - 1.8
            tracks.append(round(x,2))

        else:
            tracks.append(round(x,2))

    print(sum(tracks))
    return tracks

login()